package com.storage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.storage.bean.MySequence;
import com.storage.bean.MyVolume;
import com.storage.mapper.MySequenceMapper;
import com.storage.mapper.MyVolumeMapper;
import com.storage.service.MySequenceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

@Service
@Slf4j
public class MySequenceServiceImpl implements MySequenceService {
    @Autowired
    private MySequenceMapper mySequenceMapper;
    @Autowired
    private MyVolumeMapper myVolumeMapper;
    private final Queue<String> idQueue = new ConcurrentLinkedQueue<>();
    private final Object lock = new Object(); // 缓存加载锁
    @Override
    public String getSequence() {
        String volumename = "TEST";
        String ticket = idQueue.poll();
        if (ticket != null) {
            return ticket;
        }
        // 队列为空，需要加载缓存
        synchronized (lock) {
            // 双重检查，防止其他线程已经加载
            ticket = idQueue.poll();
            if (ticket == null) {
                log.debug("缓存id用尽，重新加载新序列");
                load(volumename);
                ticket = idQueue.poll();
            }
        }
        return ticket;
    }
    @Override
    public MyVolume load(String volumename) {
        LambdaQueryWrapper<MyVolume> myVolumeLambdaQueryWrapper = new LambdaQueryWrapper<MyVolume>();
        myVolumeLambdaQueryWrapper.eq(MyVolume::getVolumename,volumename);
        MyVolume myVolume = myVolumeMapper.selectOne(myVolumeLambdaQueryWrapper);
        String volumeid = myVolume.getVolumeid();
        MySequence mySequence = mySequenceMapper.selectById(volumeid);
        BigDecimal highmask = mySequence.getHighmask();
        BigDecimal lastno = mySequence.getLastno();
        BigDecimal lowwatermark = mySequence.getLowwatermark();
        BigDecimal highwatermark = mySequence.getHighwatermark();
        // compareTo 返回 -1 表示小于，0 表示等于，1 表示大于
        if (lastno.subtract(highmask).compareTo(lowwatermark) < 0) {
            // 改变卷的逻辑
            log.info("数据卷达到阈值，需要修改数据卷");
            return null;
        }
        // 更新数据库
        mySequence.setLastno(lastno.add(highmask.multiply(highwatermark)));
        if (mySequenceMapper.updateById(mySequence)!=1) {
            throw new RuntimeException("更新id失败");
        }
        BigDecimal newLastno = lastno;
        for (int i = 0; i < Integer.parseInt(highmask.toString()); i++) {
            newLastno = newLastno.subtract(highwatermark);
            // 1. 转为 long 避免符号问题
            long unsignedValue = newLastno.longValue() & 0xFFFFFFFFL;
            // 2. 转成 16 进制，大写补齐 8 位
            String format = String.format("%08X", unsignedValue);
            idQueue.add(format);
        }
        return myVolume;
    }
}
